﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace AnyFileManagement.UI.Controls
{
    public enum Theme
    {
        Static=0,
        D3D=1
    }

    class Button : CommandButton
    {

        private Color _staticColor = Color.FromArgb(243, 156, 18);
        private Color _hoverColor = Color.FromArgb(246, 181, 23);
        private Color _pressedColor = Color.FromArgb(207, 133, 15);
        private float _colorDecay = 0.8f;
        private ContentAlignment _textAlign = ContentAlignment.MiddleCenter;
        private Theme _theme = Theme.D3D;
        private int _extrude = 2;
        private bool _isMouseEnter;
        private bool _isMouseDown;
        private Image _image;
        private string _text = "按钮";
        private ContentAlignment _imageAlign = ContentAlignment.MiddleCenter;
        private int _radian = 5;
        private int _offsetXPer = 1;
        private int _offsetYper = 1;
        public Label lab_text;

        /// <summary>
        /// 角度X偏移量
        /// </summary>
        [Category("JUI外观"), Description("角度X偏移量")]
        public int OffsetXPer
        {
            get { return _offsetXPer; }
            set { _offsetXPer = value; }
        }

        /// <summary>
        /// 角度Y偏移量
        /// </summary>
        [Category("JUI外观"), Description("角度Y偏移量")]
        public int OffsetYper
        {
            get { return _offsetYper; }
            set { _offsetYper = value; }
        }

        /// <summary>
        /// 圆角弧度值
        /// </summary>
        [Category("JUI外观"), Description("圆角弧度值")]
        public int Radian
        {
            get { return _radian; }
            set { _radian = value; }
        }

        /// <summary>
        /// 当主题为D3D模式时，挤出高度值
        /// </summary>
        [Category("JUI外观"),Description("当主题为D3D模式时，挤出高度值")]
        public int Extrude
        {
            get { return _extrude; }
            set { _extrude = value; }
        }

        /// <summary>
        /// 图片对齐方式
        /// </summary>
        [Category("JUI外观"), Description("图片对齐方式")]
        public ContentAlignment ImageAlign
        {
            get { return _imageAlign; }
            set { _imageAlign = value; }
        }


        /// <summary>
        /// 图片
        /// </summary>
        [Category("JUI外观"), Description("图片")]
        public Image Image
        {
            get { return _image; }
            set { _image = value; }
        }

        /// <summary>
        /// 颜色衰减值
        /// </summary>
        [Category("JUI外观"), Description("颜色衰减值")]
        public float ColorDecay
        {
            get { return _colorDecay; }
            set { _colorDecay = value; }
        }

        /// <summary>
        /// 主题
        /// </summary>
        [Category("JUI外观"), Description("主题")]
        public Theme Theme
        {
            get { return _theme; }
            set { _theme = value; }
        }

        /// <summary>
        /// 文字对齐方式
        /// </summary>
        [Category("JUI外观"), Description("文字对齐方式")]
        public ContentAlignment TextAlign
        {
            get { return _textAlign; }
            set { 
                _textAlign = value;
                this.lab_text.TextAlign = _textAlign;
            }
        }
        
        /// <summary>
        /// 常规颜色
        /// </summary>
        [Category("JUI外观"), Description("常规颜色")]
        public Color StaticColor
        {
            get { return _staticColor; }
            set { _staticColor = value; }
        }

        /// <summary>
        /// 焦点颜色
        /// </summary>
        [Category("JUI外观"), Description("焦点颜色")]
        public Color HoverColor
        {
            get { return _hoverColor; }
            set { _hoverColor = value; }
        }

        /// <summary>
        /// 按下颜色
        /// </summary>
        [Category("JUI外观"), Description("按下颜色")]
        public Color PressedColor
        {
            get { return _pressedColor; }
            set { _pressedColor = value; }
        }


        /// <summary>
        /// 显示文本
        /// </summary>
        [Category("JUI外观"), Description("显示文本")]
        public string Label
        {
            get { 
                return _text;
            }
            set { 
                _text = value;
                lab_text.Text = _text;
            }
        }

        /// <summary>
        /// 构造
        /// </summary>
        public Button()
            : base()
        {
            this.ForeColor = Color.White;
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.BorderStyle = BorderStyle.None;
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.BackColor = Color.Transparent;
            InitializeComponent();
        }

        public void PerformClick()
        {
            this.OnClick(new EventArgs());
        }

        protected override void OnPaint(PaintEventArgs pevent)
        {
            this.BorderStyle = BorderStyle.None;
            base.OnPaint(pevent);
            System.Drawing.Graphics g = pevent.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            
            //重新获取文字样式
            this.lab_text.ForeColor = this.ForeColor;
            this.lab_text.Font = this.Font;
            
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            base.OnPaintBackground(e);
            System.Drawing.Graphics g = e.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            Image img = _image;
            Color CurrentColor = _staticColor;
            if (this.Enabled)
            {
                //判断是否鼠标悬停
                if (this._isMouseEnter)
                {
                    //判断是否鼠标按下
                    if (this._isMouseDown)
                    {
                        CurrentColor = this._pressedColor;
                    }
                    else
                    {
                        CurrentColor = this._hoverColor;
                    }
                }
            }
            else
            {
                if (img != null)
                {
                    img = DrawingHelper.SetOpacity(img, 0.3f);
                }
                CurrentColor = Color.FromArgb((int)(_staticColor.R * _colorDecay), (int)(_staticColor.G * _colorDecay), (int)(_staticColor.B * _colorDecay));
            }
            //判断主题模式
            switch (_theme)
            {
                case Theme.Static:
                    DrawingHelper.FillRoundRectangle(g, new SolidBrush(CurrentColor), new Rectangle(0, 0, this.Width - 1, this.Height - 1), _offsetXPer, _offsetYper, _radian);
                    ; break;
                case Theme.D3D:
                    Color bordercolor = Color.FromArgb((int)(CurrentColor.R * ColorDecay), (int)(CurrentColor.G * ColorDecay), (int)(CurrentColor.B * ColorDecay));
                    
                    if (_isMouseDown)
                    {
                        this.lab_text.Padding = new Padding(15, _extrude, 15, 0);
                        DrawingHelper.FillRoundRectangle(g, new SolidBrush(bordercolor), new Rectangle(0, this._extrude, this.Width - 1, this.Height - 1 - this._extrude), _offsetXPer, _offsetYper, _radian);
                        DrawingHelper.FillRoundRectangle(g, new SolidBrush(CurrentColor), new Rectangle(0, this._extrude+1, this.Width - 1, this.Height - 1 - this._extrude-1), _offsetXPer, _offsetYper, _radian);
                    
                    }
                    else
                    {
                        this.lab_text.Padding = new Padding(15, 0, 15, _extrude);
                        DrawingHelper.FillRoundRectangle(g, new SolidBrush(bordercolor), new Rectangle(0, 0, this.Width - 1, this.Height - 1), _offsetXPer, _offsetYper, _radian);
                        DrawingHelper.FillRoundRectangle(g, new SolidBrush(CurrentColor), new Rectangle(0, 0, this.Width - 1, this.Height - 1 - this._extrude), _offsetXPer, _offsetYper, _radian);
                    
                    }
                    ; break;
            }
            //判断图片
            if (img != null)
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                switch (_imageAlign)
                {
                    case ContentAlignment.MiddleRight:
                        int top=this.Height / 2 - this.Image.Height / 2 - 1 - (_theme == Theme.D3D ? this._extrude : 0);
                        if (_theme==Theme.D3D && _isMouseDown)
                        { 
                            top+=_extrude;
                        }
                        g.DrawImage(img, new Point(this.Width - this._image.Width - lab_text.Padding.Right,top));
                        break;
                    case ContentAlignment.MiddleLeft:
                        g.DrawImage(img, new Point(lab_text.Padding.Left, this.Height / 2 - this.Image.Height / 2 - 1 - (_theme == Theme.D3D ? this._extrude : 0)));
                        break;
                }
            }
        }

        /// <summary>
        /// 初始化
        /// </summary>
        private void InitializeComponent()
        {
            this.lab_text = new Label();
            this.SuspendLayout();
            // 
            // Button
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.Name = "Button";
            this.Font = new System.Drawing.Font("Arial", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, (byte)134);
            this.ResumeLayout(false);
            this._isMouseEnter = false;
            this._isMouseDown = false;
            //
            // lab_text
            //
            this.lab_text.BackColor = Color.Transparent;
            this.lab_text.Dock = DockStyle.Fill;
            this.lab_text.AutoSize = false;
            this.lab_text.Name = "lab_text";
            this.lab_text.Font = this.Font;
            this.lab_text.TextAlign = ContentAlignment.MiddleCenter;
            this.lab_text.ForeColor = this.ForeColor;
            this.lab_text.Padding = new Padding(15, 0, 15, 0);
            this.lab_text.Text = _text;
            this.Controls.Add(lab_text);
            this.lab_text.Click += new EventHandler((o, e) => { this.OnClick(e); });
            this.lab_text.MouseEnter += new EventHandler((o, e) => { this.OnMouseEnter(e); });
            this.lab_text.MouseLeave += new EventHandler((o, e) => { this.OnMouseLeave(e); });
            this.lab_text.MouseUp += new System.Windows.Forms.MouseEventHandler((o, e) => { this.OnMouseUp(e); });
            this.lab_text.MouseDown += new System.Windows.Forms.MouseEventHandler((o, e) => { this.OnMouseDown(e); });
            this.lab_text.TextChanged += new EventHandler((o, e) => { this.OnTextChanged(e); this.Invalidate(); });
            this.lab_text.DoubleClick += new EventHandler((o, e) => { this.OnDoubleClick(e); this.Invalidate(); });
         
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            this._isMouseEnter = true;
            this.Invalidate();
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            this._isMouseEnter = false;
            this.Invalidate();
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            this._isMouseDown = true;
            this.Invalidate();
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            this._isMouseDown = false;
            this.Invalidate();
        }
         

    }
}
